#pragma once
#include "rtp.h"

/*****************
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI|  Type   |
+---------------+
*****************/
typedef struct {
    unsigned char bit5TYPE : 5;
    unsigned char bit2NRI : 2;
    unsigned char bit1F : 1;
} RTP_NALU_HEADER_S;

/****************
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI|  Type   |
+---------------+
*****************/
typedef struct {
    unsigned char Bit5TYPE : 5;
    unsigned char BitNRI : 2;
    unsigned char BitF : 1;
} RTP_FU_INDICATOR_S;

/******************
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R|  Type   |
+---------------+
*******************/
typedef struct {
    unsigned char Bit5TYPE : 5;
    unsigned char Bit1R : 1;
    unsigned char Bit1E : 1;
    unsigned char Bit1S : 1;
} RTP_FU_HEADER_S;

enum NALUType {
    H264_SEI = 6,
    H264_SPS = 7,
    H264_PPS = 8,
    AUD      = 9,
    IDR      = 5,
    SLICE    = 1,
    STAP_A   = 24,
    STAP_B   = 25,
    MTAP16   = 26,
    MTAP24   = 27,
    FU_A     = 28,
    FU_B     = 29
};

/*
 常用Nalu_type:
 0x67 (0 11 00111) SPS          非常重要     type = 7
 0x68 (0 11 01000) PPS          非常重要     type = 8
 0x65 (0 11 00101) IDR  关键帧  非常重要     type = 5
 0x61 (0 10 00001) I帧      重要             type = 1
 0x41 (0 10 00001) P帧      重要             type = 1
 0x01 (0 00 00001) B帧      不重要           type = 1
 0x06 (0 00 00110) SEI      不重要           type = 6
*/

using ParseFunc =
  std::function<void(PayloadType, u_int32_t time_stamp, u_int32_t nalutype, std::vector<u_char>&)>;
class Parse {
private:
    uint32_t last_u32SeqNum{0};
    bool     UnpackRtpHead(PayloadType pt, u_char* rtp_head, RTP_HEADER_S& rtphead);

    // H264
    bool                b_start_{false};  //是否开始回调媒体流数据，通常sps开始
    std::vector<u_char> one_pack_h264_;
    void                ParseH264(std::vector<u_char> one_rtp_pack);

    int       count{0};
    ParseFunc parse_func_{nullptr};

public:
    Parse(/* args */){};
    ~Parse(){};

    void SetParseFunc(ParseFunc f) {
        parse_func_ = f;
    }

    bool PushRtpPack(PayloadType pt, std::vector<u_char> one_rtp_pack);
};

//  Parse:: Parse(/* args */)
// {
// }

//  Parse::~ Parse()
// {
// }
